import 'package:dio/dio.dart';
import 'package:enjoy_plus_test/utils/eventbus.dart';
import 'package:enjoy_plus_test/utils/toast.dart';
import 'package:enjoy_plus_test/utils/token.dart';
import 'package:flutter/cupertino.dart';
import 'package:logger/logger.dart';

import '../main.dart';

class NetworkService {
  var logger = Logger();
  final _dio = Dio();
  // 构造函数是在类被实例化的时候会自动调用
  // 如果不写在构造函数里面就需要写在每个请求方法中，造成代码冗余，并且不能保证_dio对象的配置的一致性。
  NetworkService() {
    _dio.options.baseUrl = 'https://live-api.itheima.net';
    //设置连接超时时间
    /*有可能网络信号不好、服务器维护或者网络拥塞等原因，导致连接过程变得缓慢，就有可能连接服务器超时*/
    _dio.options.connectTimeout = const Duration(seconds: 5);
    //设置接收超时时间
    // 假设服务器返回数据时数据量过大，即负载过高，或者网络堵塞，就会导致返回的数据比较慢，就有可能超时，即receiveTimeout
    _dio.options.receiveTimeout = const Duration(seconds: 5);
    //设置请求头
    _dio.options.headers = {"Content-Type": "application/json"};
    //添加请求和响应拦截器
    _addInterceptors();
  }
  void _addInterceptors() {
    _dio.interceptors.add(
      InterceptorsWrapper(
        // 请求拦截器
        onRequest: (options, handler) async {
          final token = TokenManager().getToken();
          if (token != null) {
            options.headers['Authorization'] = 'Bearer $token';
          }
          return handler.next(options);
        },
        //   响应拦截器
        onResponse: (response, handler) async {
          return handler.next(response);
        },
        //   响应错误时统一处理
        onError: (DioException error, handler) {
          return handler.next(error);
        },
      ),
    );
  }

  dynamic handleResponse(Response response) {
    if (response.statusCode! >= 200 && response.statusCode! < 300) {
      return response.data;
    } else {
      throw Exception('请求错误，状态码：${response.statusCode}');
    }
  }

  dynamic handleError(error) {
    if (error is DioException) {
      if (error.type == DioExceptionType.connectionTimeout ||
          error.type == DioExceptionType.receiveTimeout) {
        throw Exception('网络连接超时');
      } else if (error.type == DioExceptionType.badResponse) {
        if (error.response?.statusCode == 401) {
          TokenManager().removeToken();
          // 发送事件
          eventBus.fire(LogoutEvent(''));
          // 先移除现有路由，然后推送新路由
          // navigatorKey.currentState?.pushNamedAndRemoveUntil(
          //   '/login',
          //   (route) => true,//这里返回 true 表示移除所有现有路由
          // );
        } else {
          throw Exception('响应错误，状态码：${error.response?.statusCode}');
        }
      } else {
        throw Exception('未知错误：$error');
      }
    }
  }

  // Future用于表明get方法是异步执行的，dynamic表示乐意返回任意类型，url的类型是String,params的类型是Map键值对，键是String类型，值是动态类型
  Future<dynamic> get(String url, {Map<String, dynamic>? params}) async {
    try {
      final response = await _dio.get(url, queryParameters: params);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  Future<dynamic> post(String url, {dynamic data}) async {
    try {
      final response = await _dio.post(url, data: data);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  Future<dynamic> put(String url, {dynamic data}) async {
    try {
      final response = await _dio.put(url, data: data);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }

  Future<dynamic> delete(String url, {dynamic? data}) async {
    try {
      final response = await _dio.delete(url, data: data);
      return handleResponse(response);
    } catch (e) {
      return handleError(e);
    }
  }
}

// 导出
final http = NetworkService();
